<template>
  <div class="relative">
    <button class="group flex justify-between items-center cursor-pointer w-full" @click="isOpen = !isOpen" @keydown.esc="isOpen = false">
      <div class="flex space-x-2 items-center text-gray-900 truncate">
        <RiMapPin2Fill class="h-4 w-4 flex-none transition-opacity opacity-25 group-hover:opacity-100" />
        <div v-if="ipLatLng" class="truncate">
          Autour de moi
        </div>
        <div v-else class="font-bold truncate">
          {{ $route.query.city }}
        </div>
      </div>
      <ChevronDownIcon class="text-gray-500 h-4 w-4 group-hover:text-gray-900 flex-none" />
    </button>

    <transition name="fade-in">
      <div
        v-if="isOpen"
        v-click-outside="onClickOutside"
        class="mt-2 absolute z-40 bg-white border shadow-xl text-[15px] w-[350px]"
        @keydown.esc="isOpen = false"
      >
        <div class="p-4 pb-0 space-y-3">
          <div class="font-medium">
            {{ label }}
          </div>

          <FacetSearch ref="facetSearch" v-model="searchValue" placeholder="Nom ou code postal" @input="handleInput" />
        </div>

        <div class="text-sm">
          <div class="flex flex-col py-2">
            <button
              v-for="suggestion in suggestions"
              :key="suggestion.id"
              class="px-4 py-2 cursor-pointer flex justify-between truncate flex-1 group !outline-none focus-visible:bg-[#E3E3FD]"
              @click="handleSelectedAdress(suggestion)"
            >
              <div class="flex items-center">
                <LocationMarkerIcon class="flex-none mr-2 transition text-gray-400 group-hover:text-jva-blue-500 group-hover:scale-110" width="16" height="16" />
                <div class="truncate">
                  {{ suggestion.city }}
                </div>
              </div>

              <div class="text-gray-600 ml-1 font-light">
                {{ suggestion.postcode }}
              </div>
            </button>
          </div>

          <div class="border-t px-6 py-3 flex justify-end">
            <button
              :class="[
                {'text-gray-400 pointer-events-none': !$route.query.city},
                {'text-jva-blue-500 cursor-pointer': $route.query.city}
              ]"
              :disabled="!$route.query.city"
              @click="handleSelectedAdress(null)"
            >
              Effacer
            </button>
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
import { debounce } from 'lodash'
import AlgoliaQueryBuilder from '@/mixins/algolia-query-builder'
import FacetSearch from '@/components/section/search/FacetSearch.vue'

export default {
  components: {
    FacetSearch
  },
  mixins: [AlgoliaQueryBuilder],
  props: {
    label: {
      type: String,
      required: true
    },
    ipLatLng: {
      type: String,
      default: null
    }
  },
  data () {
    return {
      isOpen: false,
      searchValue: this.$route.query.city,
      fetchSuggestions: [],
      initialSuggestions: [
        {
          id: 'initial_1',
          city: 'Paris',
          aroundLatLng: '48.859,2.347',
          postcode: '75001'
        },
        {
          id: 'initial_2',
          city: 'Marseille',
          aroundLatLng: '43.282,5.405',
          postcode: '13001'
        },
        {
          id: 'initial_3',
          city: 'Lyon',
          aroundLatLng: '45.758,4.835',
          postcode: '69001'
        },
        {
          id: 'initial_4',
          city: 'Toulouse',
          aroundLatLng: '43.603746,1.434497',
          postcode: '31000'
        },
        {
          id: 'initial_5',
          city: 'Bordeaux',
          aroundLatLng: '44.851895,-0.587877',
          postcode: '33200'
        }
      ]
    }
  },
  computed: {
    suggestions () {
      return this.fetchSuggestions.length
        ? this.fetchSuggestions
        : [
            ...this.$cookies.get('localisation-history') ?? [],
            ...this.initialSuggestions
          ].reduce((unique, item) => (unique.find(i => i.aroundLatLng == item.aroundLatLng) ? unique : [...unique, item]), []).slice(0, 5)
    }
  },
  watch: {
    '$route.query.city' (newVal) {
      this.searchValue = newVal
    },
    async isOpen (isOpen) {
      if (isOpen) {
        await this.$nextTick()
        this.$refs.facetSearch.$refs?.input?.focus()
      }
    }
  },
  methods: {
    reset () {
      this.searchValue = null
    },
    onClickOutside () {
      this.isOpen = false
    },
    async fetchGeoSuggestions () {
      const { data } = await this.$axios.get('https://api-adresse.data.gouv.fr/search', {
        params: {
          q: this.searchValue,
          limit: 5,
          type: 'municipality'
        }
      })

      const formatOptions = data.features.map((option) => {
        return {
          ...option.properties,
          aroundLatLng: `${option.geometry.coordinates[1]},${option.geometry.coordinates[0]}`,
          typeLabel: this.$options.filters.label(option.properties.type, 'geoType')
        }
      })
      this.fetchSuggestions = formatOptions
    },
    handleInput (payload) {
      this.searchValue = payload
      if (this.timeout) {
        this.timeout.cancel()
      }
      this.timeout = debounce(() => {
        if (this.searchValue?.length < 3) {
          if (!this.searchValue) {
            this.fetchSuggestions = []
          }
          return
        }
        this.fetchGeoSuggestions()
      }, 275)
      this.timeout()
    },
    handleSelectedAdress (suggestion) {
      this.$router.push({
        path: this.$route.path,
        query: {
          ...this.$route.query,
          aroundLatLng: suggestion?.aroundLatLng,
          city: suggestion?.city,
          page: undefined
        }
      })
      this.isOpen = false
      this.fetchSuggestions = []

      if (suggestion) {
        this.setHistory(suggestion)
      }
    },
    setHistory (suggestion) {
      const history = [
        {
          aroundLatLng: suggestion.aroundLatLng,
          city: suggestion.city,
          postcode: suggestion.postcode
        },
        ...this.$cookies.get('localisation-history') ?? []
      ].reduce((unique, item) => (unique.find(i => i.aroundLatLng == item.aroundLatLng) ? unique : [...unique, item]), []).slice(0, 5)
      this.$cookies.set('localisation-history', history)
    }
  }
}
</script>
